﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace Beryl.OrderControllers.DataStructural
{
    public class proOrderStructural
    {
        private static proOrderStructural instance = null;
        private static readonly object uniqueLock = new object();
        public static proOrderStructural Instance
        {
            get
            {
                lock (uniqueLock)
                {
                    if (instance == null)
                    {
                        instance = new proOrderStructural();
                    }
                }
                return instance;
            }
        }
        public proOrderStructural() { }

        // BOM数据结构化
        public Dictionary<string,Dictionary<string,string>> getBomData(DataRow[] BomData)
        {
            var BomDataObj = new Dictionary<string, Dictionary<string, string>>();
            Dictionary<string, string> keys = null;
            string cInOutType1 = "";
            string cMatandResNo = "";
            for (int i = 0; i < BomData.Length; ++i)
            {
                string cMatNo = BomData[i]["cMatNo"].ToString();
                string cInOutType = BomData[i]["cInOutType"].ToString();
                if (cInOutType == "input")
                {
                    cInOutType1 = cInOutType;
                    cMatandResNo = BomData[i]["cMatandResNo"].ToString();
                }
                if (cInOutType == "output")
                {
                    cInOutType1 = cInOutType;
                }
                if (!BomDataObj.ContainsKey(cMatNo))
                {
                    BomDataObj.Add(cMatNo, new Dictionary<string, string>());
                }
                keys = new Dictionary<string, string>
                {
                    { "cInOutType", cInOutType1 },
                    { "cMatandResNo", cMatandResNo }
                };
                BomDataObj[cMatNo] = keys;
            }
            return BomDataObj;
        }

        // 物料主数据结构化
        public Dictionary<string, Dictionary<string, string>> getMatData(DataRow[] MatData)
        {
            var MatDataObj = new Dictionary<string, Dictionary<string, string>>();
            Dictionary<string, string> keys = null;
            for (int i = 0; i < MatData.Length; ++i)
            {
                string cMatNo = MatData[i]["cMatNo"].ToString();
                string cMatName = MatData[i]["cMatName"].ToString();
                string dProBatch = MatData[i]["dProBatch"].ToString();
                string cProMethod = MatData[i]["cProMethod"].ToString();
                string cCateNo = MatData[i]["cCateNo"].ToString();
                string cSpecifucation = MatData[i]["cSpecifucation"].ToString();
                if(!MatDataObj.ContainsKey(cMatNo))
                {
                    MatDataObj.Add(cMatNo, new Dictionary<string, string>());
                }
                keys = new Dictionary<string, string>
                {
                    { "dProBatch", dProBatch },
                    { "cProMethod", cProMethod },
                    { "cSpecifucation", cSpecifucation },
                    { "cCateNo", cCateNo }
                };
                MatDataObj[cMatNo] = keys;
            }
            return MatDataObj;
        }

        // 生成订单结构化
        public Dictionary<string, Dictionary<string, string>> getPlanOrder(DataRow[] planOrder)
        {
            var planOrderObj = new Dictionary<string, Dictionary<string, string>>();
            Dictionary<string, string> keys = null;
            for(int i = 0; i < planOrder.Length; ++i)
            {
                // 生成订单编号 
                string cPOrderNo = planOrder[i]["cPOrderNo"].ToString();
                if(!planOrderObj.ContainsKey(cPOrderNo))
                {
                    planOrderObj.Add(cPOrderNo, new Dictionary<string, string>());
                }
                keys = new Dictionary<string, string>
                {
                    { "cMatNo", planOrder[i]["cMatNo"].ToString() },
                    { "dPlanQty", planOrder[i]["dPlanQty"].ToString() },
                    { "dPlanQty1", planOrder[i]["dPlanQty1"].ToString() },
                    { "dDeliveryDate", planOrder[i]["dDeliveryDate"].ToString() },
                    { "cProductDepNo", planOrder[i]["cProductDepNo"].ToString() },
                    //重工单标识
                    { "cReworkFlag", planOrder[i]["cReworkFlag"].ToString() },
                    //插单标识
                    { "cOFlag", planOrder[i]["cOFlag"].ToString() },
                    //大批量订单开始生产日期
                    { "cBigBegProDate", planOrder[i]["cBigBegProDate"].ToString() },
                    //生产批量倍数
                    { "iBatchMult", "" },
                    { "MotypeCode", planOrder[i]["MotypeCode"].ToString() },
                    { "dProBatch", planOrder[i]["dProBatch"].ToString() },
                    { "Coefficient", planOrder[i]["Coefficient"].ToString() },
                    { "putProQty", planOrder[i]["putProQty"].ToString() }
                };
                planOrderObj[cPOrderNo] = keys;
                string jsonString = CommonMethod.Instance.dataRowToJson(planOrder[i]);
                planOrderObj[cPOrderNo].Add("json", jsonString);
            }
            return planOrderObj;
        }

        // 工艺路线结构化
        public Dictionary<string,Dictionary<string,Dictionary<string,string>>> getRouting(DataRow[] Routing)
        {
            var RoutingObj = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
            try
            {
                for (int i = 0; i < Routing.Length; ++i)
                {
                    string cMatNo = Routing[i]["cMatNo"].ToString();
                    if (!RoutingObj.ContainsKey(cMatNo))
                    {
                        RoutingObj.Add(cMatNo, new Dictionary<string, Dictionary<string, string>>());
                    }
                    string cOperationNo = Routing[i]["cOperationNo"].ToString();
                    if (!RoutingObj[cMatNo].ContainsKey(cOperationNo))
                    {
                        RoutingObj[cMatNo].Add(cOperationNo, new Dictionary<string, string>());
                        RoutingObj[cMatNo][cOperationNo].Add("cOperationName", Routing[i]["cOperationName"].ToString());
                        RoutingObj[cMatNo][cOperationNo].Add("cOpSeq", Routing[i]["cOpSeq"].ToString());
                        RoutingObj[cMatNo][cOperationNo].Add("cCombination", Routing[i]["cCombination"].ToString());
                        RoutingObj[cMatNo][cOperationNo].Add("cOperationNo", Routing[i]["cOperationNo"].ToString());
                        RoutingObj[cMatNo][cOperationNo].Add("dTransferTime", Routing[i]["dTransferTime"].ToString());
                    }
                }
            }
            catch(Exception e)
            {
                throw e;
            }
            return RoutingObj;
        }

        //定义生成订单和对应的子销售订单对象obj{生成订单{子销售订单[]}}
        public Dictionary<string, Dictionary<string, Dictionary<string, string>>> getobj(List<string> cPOrderNoArr, DataRow[] planOrder)
        {
            var obj = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
            Dictionary<string, string> keys = null;
            for(int i = 0; i < cPOrderNoArr.Count; ++i)
            {
                string cPOrderNo = cPOrderNoArr[i];
                if(!obj.ContainsKey(cPOrderNo))
                {
                    obj.Add(cPOrderNo, new Dictionary<string, Dictionary<string, string>>());
                }
                for(int j = 0; j < planOrder.Length; ++j)
                {
                    if (planOrder[j]["cPOrderNo"].ToString() == cPOrderNo)
                    {
                        string cSourceNo = planOrder[j]["cSourceNo"].ToString();
                        if (!obj[cPOrderNo].ContainsKey(cSourceNo))
                        {
                            obj[cPOrderNo].Add(cSourceNo, new Dictionary<string, string>());
                        }
                        keys = new Dictionary<string, string>
                        {
                            { "dQty", planOrder[j]["dQty"].ToString() },
                            { "dQty2", planOrder[j]["dQty2"].ToString() },
                            { "dQty3", planOrder[j]["dQty3"].ToString() },
                            { "dPlanQty", planOrder[j]["dPlanQty"].ToString() },
                            { "ddQty", "0" },
                            { "proLotOrderNo", "0" }
                        };
                        obj[cPOrderNo][cSourceNo] = keys;
                    }   
                }
            }
            return obj;
        }

        // 按批次数量拆批
        public Dictionary<string, Dictionary<string, Dictionary<string, string>>> getProOrder(Dictionary<string, Dictionary<string, string>> planOrderObj, 
            Dictionary<string, Dictionary<string, string>> MatDataObj,bool cIndependentBatch, Dictionary<string, Dictionary<string, Dictionary<string, string>>> obj,
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> RoutingObj, Dictionary<string, Dictionary<string, string>> BomDataObj,string loginUser)
        {
            var proOrderObj = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
            Dictionary<string, Dictionary<string, string>> planOrderObjPara = new Dictionary<string, Dictionary<string, string>>();
            float length = 0;
            foreach (var cPOrderNo in planOrderObj.Keys)
            {
                // 物料编号
                string cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                // 计划订单数量
                string dPlanQty = planOrderObj[cPOrderNo]["dPlanQty"];
                string dPlanQty1 = planOrderObj[cPOrderNo]["dPlanQty"];
                // 生产部门
                string cProductDepNo = planOrderObj[cPOrderNo]["cProductDepNo"];
                string MotypeCode = planOrderObj[cPOrderNo]["MotypeCode"];
                string str = "";
                str = MotypeCode;
                // 交货期
                string dDeliveryDate = planOrderObj[cPOrderNo]["dDeliveryDate"];
                // 流水号
                int serialNum = 0;
                // 生产订单编号
                //let proOrderNo = cPOrderNo.replace(/P/, "M");
                string proOrderNo = cPOrderNo;
                float c = 0;   //钉卷预拆批批次总数
                float c1 = 0;   //加工预拆批批次总数
                if(MatDataObj.ContainsKey(cMatNo))
                {
                    // 批次初始化为0
                    float batch = 0;
                    float batchNum = 0;
                    // let batchNum = MatDataObj[cMatNo].dProBatch;  //拆批量
                    if (planOrderObj[cPOrderNo]["dProBatch"] != "")
                    {
                        batchNum = float.Parse(planOrderObj[cPOrderNo]["dProBatch"]);
                    }

                    //初始值没被选中时执行
                    if(!cIndependentBatch)
                    {
                        cIndependentBatch = CommonMethod.Instance.IndependentBatch(float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]), batchNum);//重新赋值
                    }
                   
                    
                    // 根据是否独立成批提前计算批数
                    if (!cIndependentBatch)
                    {
                        c = (float)(c + Math.Floor(float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) / batchNum));
                        if (c == 0)
                        {
                            c = 1;
                        }
                        c1 = (float)(c1 + Math.Floor(float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) / batchNum));
                        if (c1 == 0)
                        {
                            c1 = 1;
                        }
                    }
                    else
                    {
                        c = (float)(c + Math.Ceiling(float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) / batchNum));
                        if(planOrderObj[cPOrderNo]["dPlanQty1"] != "")
                        {
                            c1 = (float)(c1 + Math.Ceiling(float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) / batchNum));
                        }
                    }
                    // 钉卷大于加工
                    if (c >= c1 && c !=0 && c1!= 0)
                    {
                        float D_J = -1;
                        if (cIndependentBatch)
                        {
                            D_J = float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) - c1 * batchNum;
                        }
                        
                        float flag = 0;
                        while (float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) > 0)
                        {
                            // 初始拆批量
                            batchNum = float.Parse(planOrderObj[cPOrderNo]["dProBatch"]);
                            // 加工批次的流水号
                            serialNum = CommonMethod.Instance.GenerateID2(++serialNum, "000");
                            if (!proOrderObj.ContainsKey(proOrderNo))
                            {
                                length++;
                                proOrderObj.Add(proOrderNo,new Dictionary<string, Dictionary<string, string>>());
                            }
                            // 加工批次编号
                            string proLotOrderNo = cPOrderNo + str + "-" + serialNum;
                            if (!proOrderObj[cPOrderNo].ContainsKey(proLotOrderNo))
                            {
                                proOrderObj[cPOrderNo].Add(proLotOrderNo, new Dictionary<string, string>());
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("cProductDepNo", cProductDepNo);
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("dDeliveryDate", dDeliveryDate);
                            }

                            // 当数量小于2倍的批次数时，直接加在最后批次（需要配置项为true）
                            if (float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) < 2 * batchNum && !cIndependentBatch)
                            {
                                // 最后一批的数量
                                proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = planOrderObj[cPOrderNo]["dPlanQty1"];
                                // 更新拆批量
                                batchNum = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]);
                                proOrderObj = TraverseSource(obj, cPOrderNo,planOrderObj, batchNum, proOrderObj, proLotOrderNo,
                                                            RoutingObj, BomDataObj, loginUser, serialNum, c1, D_J, out planOrderObjPara);
                                planOrderObj = planOrderObjPara;
                                planOrderObj[cPOrderNo]["dPlanQty1"] = "0";
                            }
                            else
                            {
                                // 判断订单需求数量是否大于拆批量
                                if (float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) > batchNum)
                                {
                                    // 批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) > batchNum ? batchNum.ToString() : planOrderObj[cPOrderNo]["dPlanQty1"];

                                    proOrderObj = TraverseSource(obj, cPOrderNo, planOrderObj, batchNum, proOrderObj, proLotOrderNo,
                                                                        RoutingObj, BomDataObj, loginUser, serialNum, c, D_J, out planOrderObjPara);
                                    planOrderObj = planOrderObjPara;
                                    // 按拆批量扣减需求
                                    float outValue = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]);
                                    outValue -= batchNum;
                                    planOrderObj[cPOrderNo]["dPlanQty1"] = outValue.ToString();

                                }
                                else
                                {
                                    // 最后一批批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = planOrderObj[cPOrderNo]["dPlanQty1"];
                                    // 更新拆批量
                                    batchNum = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]);
                                    proOrderObj = TraverseSource(obj, cPOrderNo, planOrderObj, batchNum, proOrderObj, proLotOrderNo,
                                                                        RoutingObj, BomDataObj, loginUser, serialNum, c, D_J, out planOrderObjPara);
                                    planOrderObj = planOrderObjPara;
                                    planOrderObj[cPOrderNo]["dPlanQty1"] = "0";
                                }
                            }
                        }
                        while (D_J > 0)
                        {
                            // 初始拆批量
                            if (planOrderObj[cPOrderNo]["dProBatch"] != "")
                            {
                                batchNum = float.Parse(planOrderObj[cPOrderNo]["dProBatch"]);
                            }
                            // 加工批次的流水号
                            serialNum = serialNum + (int)c;
                            serialNum = CommonMethod.Instance.GenerateID2(++serialNum, "000");
                            // 加工批次编号
                            string proLotOrderNo = cPOrderNo + str + "-" + serialNum;
                            if (!proOrderObj[cPOrderNo].ContainsKey(proLotOrderNo))
                            {
                                proOrderObj[cPOrderNo].Add(proLotOrderNo, new Dictionary<string, string>());
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("cProductDepNo", cProductDepNo);
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("dDeliveryDate", dDeliveryDate);
                            }
                            // 当数量小于2倍的批次数时，直接加在最后批次（需要配置项为true）
                            if (D_J < 2 * batchNum && !cIndependentBatch)
                            {
                                // 最后一批的数量
                                proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = D_J.ToString();
                                // 更新拆批量
                                batchNum = D_J;
                                proOrderObj = TraverseSource1(obj, BomDataObj, cPOrderNo, planOrderObj, batchNum, proOrderObj,
                                                                    proLotOrderNo, RoutingObj, loginUser, serialNum, c1, flag, out planOrderObjPara);
                                D_J = 0;
                                planOrderObj = planOrderObjPara;
                            }
                            else
                            {
                                // 判断订单需求数量是否大于拆批量
                                if (D_J > batchNum)
                                {
                                    // 批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = D_J > batchNum ? batchNum.ToString() : D_J.ToString();
                                    // 按拆批量扣减需求
                                    D_J -= batchNum;
                                    proOrderObj = TraverseSource1(obj, BomDataObj, cPOrderNo, planOrderObj, batchNum, proOrderObj,
                                                                        proLotOrderNo, RoutingObj, loginUser, serialNum, c1, flag, out planOrderObjPara);
                                    planOrderObj = planOrderObjPara;
                                }
                                else
                                {
                                    // 最后一批批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = D_J.ToString();

                                    // 更新拆批量
                                    batchNum = D_J;
                                    proOrderObj = TraverseSource1(obj, BomDataObj, cPOrderNo, planOrderObj, batchNum, proOrderObj,
                                                                        proLotOrderNo, RoutingObj, loginUser, serialNum, c1, flag, out planOrderObjPara);
                                    D_J = 0;
                                    planOrderObj = planOrderObjPara;
                                }
                            }
                        }
                    }
                    else
                    {
                        float D_J = 0;
                        if (planOrderObj[cPOrderNo]["dPlanQty1"] != "" && planOrderObj[cPOrderNo]["dPlanQty"] != null)
                        {
                            D_J = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]) - float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]);
                        }

                        int flag = 1;
                        while (float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) > 0)
                        {
                            // 初始拆批量
                            if (planOrderObj[cPOrderNo]["dProBatch"] != "")
                            {
                                batchNum = float.Parse(planOrderObj[cPOrderNo]["dProBatch"]);
                            }
                            // 加工批次的流水号
                            serialNum =CommonMethod.Instance.GenerateID2(++serialNum, "000");
                            if (!proOrderObj.ContainsKey(proOrderNo))
                            {
                                length++;
                                proOrderObj.Add(proOrderNo, new Dictionary<string, Dictionary<string, string>>());
                            }
                            // 加工批次编号
                            string proLotOrderNo = cPOrderNo + str + serialNum;
                            if (!proOrderObj[cPOrderNo].ContainsKey(proLotOrderNo))
                            {
                                proOrderObj[cPOrderNo].Add(proLotOrderNo,new Dictionary<string, string>());
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("cProductDepNo", cProductDepNo);
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("dDeliveryDate", dDeliveryDate);
                            }
                            // 当数量小于2倍的批次数时，直接加在最后批次（需要配置项为true）
                            if (float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) < 2 * batchNum && !cIndependentBatch)
                            {
                                // 最后一批的数量
                                proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = planOrderObj[cPOrderNo]["dPlanQty"];
                                // 更新拆批量
                                batchNum = float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]);
                                proOrderObj = TraverseSource(obj, cPOrderNo,planOrderObj, batchNum, proOrderObj, proLotOrderNo,
                                                                    RoutingObj, BomDataObj, loginUser, serialNum, c, -99999, out planOrderObjPara);
                                planOrderObj = planOrderObjPara;
                                planOrderObj[cPOrderNo]["dPlanQty"] = "0";
                            }
                            else
                            {
                                // 判断订单需求数量是否大于拆批量
                                if (float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) > batchNum)
                                {
                                    // 批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) > batchNum ? batchNum.ToString() : planOrderObj[cPOrderNo]["dPlanQty"];


                                    proOrderObj = TraverseSource(obj, cPOrderNo, planOrderObj, batchNum, proOrderObj, proLotOrderNo,
                                                                        RoutingObj, BomDataObj, loginUser, serialNum, c, -99999, out planOrderObjPara);
                                    planOrderObj = planOrderObjPara;
                                    // 按拆批量扣减需求
                                    float outValue = float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]);
                                    outValue -= batchNum;
                                    planOrderObj[cPOrderNo]["dPlanQty"] = outValue.ToString();
                                }
                                else
                                {
                                    // 最后一批批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = planOrderObj[cPOrderNo]["dPlanQty"];
                                    // 更新拆批量
                                    batchNum = float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]);
                                    proOrderObj = TraverseSource(obj, cPOrderNo, planOrderObj, batchNum, proOrderObj, proLotOrderNo,
                                                                        RoutingObj, BomDataObj, loginUser, serialNum, c, -99999, out planOrderObjPara);
                                    planOrderObj = planOrderObjPara;
                                    planOrderObj[cPOrderNo]["dPlanQty"] = "0";
                                }
                            }
                        }
                        while (D_J > 0)
                        {
                            // 初始拆批量
                            if (planOrderObj[cPOrderNo]["dProBatch"] != "")
                            {
                                batchNum = float.Parse(planOrderObj[cPOrderNo]["dProBatch"]);
                            }
                           // batchNum = planOrderObj[cPOrderNo].dProBatch;
                            // 加工批次的流水号
                            serialNum = serialNum + (int)c;
                            serialNum = CommonMethod.Instance.GenerateID2(++serialNum, "000");
                            // 加工批次编号
                            string proLotOrderNo = cPOrderNo + str + "-" + serialNum;
                            if (!proOrderObj[cPOrderNo].ContainsKey(proLotOrderNo))
                            {
                                proOrderObj[cPOrderNo].Add(proLotOrderNo,new Dictionary<string, string>());
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("cProductDepNo", cProductDepNo);
                                proOrderObj[cPOrderNo][proLotOrderNo].Add("dDeliveryDate", dDeliveryDate);
                            }
                            // 当数量小于2倍的批次数时，直接加在最后批次（需要配置项为true）
                            if (D_J < 2 * batchNum && !cIndependentBatch)
                            {
                                // 最后一批的数量
                                proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = D_J.ToString();
                                // 更新拆批量
                                batchNum = D_J;
                                proOrderObj = TraverseSource1(obj, BomDataObj, cPOrderNo, planOrderObj, batchNum, proOrderObj,
                                                                    proLotOrderNo, RoutingObj, loginUser, serialNum, c, flag, out planOrderObjPara);
                                D_J = 0;
                                planOrderObj = planOrderObjPara;
                            }
                            else
                            {
                                // 判断订单需求数量是否大于拆批量
                                if (D_J > batchNum)
                                {
                                    // 批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = D_J > batchNum ? batchNum.ToString() : D_J.ToString();
                                    // 按拆批量扣减需求
                                    D_J -= batchNum;
                                    proOrderObj = TraverseSource1(obj, BomDataObj, cPOrderNo, planOrderObj, batchNum, proOrderObj,
                                                                        proLotOrderNo, RoutingObj, loginUser, serialNum, c, flag, out planOrderObjPara);
                                    planOrderObj = planOrderObjPara;
                                }
                                else
                                {
                                    // 最后一批批次数量
                                    proOrderObj[proOrderNo][proLotOrderNo]["batchNum"] = D_J.ToString();
                                    // 更新拆批量
                                    batchNum = D_J;
                                    proOrderObj = TraverseSource1(obj, BomDataObj, cPOrderNo, planOrderObj, batchNum, proOrderObj,
                                                                        proLotOrderNo, RoutingObj, loginUser, serialNum, c, flag, out planOrderObjPara);
                                    D_J = 0;
                                    planOrderObj = planOrderObjPara;
                                }
                            }
                        }
                    }
                }
            }
            return proOrderObj;
        }

        private Dictionary<string, Dictionary<string, Dictionary<string, string>>> TraverseSource1(Dictionary<string, Dictionary<string, Dictionary<string, string>>> obj, 
            Dictionary<string, Dictionary<string, string>> BomDataObj, 
            string cPOrderNo, Dictionary<string, Dictionary<string, string>> planOrderObj, float batchNum, 
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> proOrderObj,
            string proLotOrderNo, Dictionary<string, Dictionary<string, Dictionary<string, string>>> RoutingObj, string loginUser, int serialNum, float c, float flag, 
            out Dictionary<string, Dictionary<string, string>> planOrderObjPara)
        {
            List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
            Dictionary<string, string> keys = null;
            float ddQty = 0;
            // 生产订单编号
            string proOrderNo = cPOrderNo;
            // 生产部门
            string cProductDepNo = planOrderObj[cPOrderNo]["cProductDepNo"];
            //订单类别
            string MotypeCode = planOrderObj[cPOrderNo]["MotypeCode"];
            string Coefficient = planOrderObj[cPOrderNo]["Coefficient"];
            string str = "";
            str = MotypeCode;
            // 交货期
            string dDeliveryDate = planOrderObj[cPOrderNo]["dDeliveryDate"];
            string cReworkFlag = "";
            string cOFlag = "";
            string cBigBegProDate = "";
            float iBatchMult = 0;
            if (planOrderObj[cPOrderNo].ContainsKey("josn"))
            {
                string json = planOrderObj[cPOrderNo]["josn"];
                JArray jsonArr = (JArray)JsonConvert.DeserializeObject(json);
                //重工单标识
                cReworkFlag = jsonArr[11].ToString();
                //插单标识
                cOFlag = jsonArr[12].ToString();
                //大批量订单开始生产日期
                cBigBegProDate = jsonArr[13].ToString();
                //生产批量倍数
                iBatchMult = 0;
            }else
            {
                //重工单标识
                cReworkFlag = planOrderObj[cPOrderNo]["cReworkFlag"];
                //插单标识
                cOFlag = planOrderObj[cPOrderNo]["cOFlag"];
                //大批量订单开始生产日期
                cBigBegProDate = planOrderObj[cPOrderNo]["cBigBegProDate"];
                //生产批量倍数
                iBatchMult = 0;
            }
            // 物料编号
            string cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
            if(flag == 0)
            {
                // 指令类型
                string cInOutType = BomDataObj[cMatNo]["cInOutType"];
                if (cInOutType == "output")
                {
                    // 半成品（钉卷批次）
                    cMatNo = BomDataObj[cMatNo]["cMatandResNo"];
                }
            }
            else
            {

            }
            // 配比
            string cCombination = "";
            if (RoutingObj.ContainsKey(cMatNo))
            {
                foreach(var RoutingCode in RoutingObj[cMatNo].Keys)
                {
                    cCombination = RoutingObj[cMatNo][RoutingCode]["cCombination"];
                }
            }
            string ccSourceNo = "";
            foreach(var cSourceNo in obj[cPOrderNo].Keys)
            {
                ccSourceNo = cSourceNo;
            }
            // 条码值
            string cBarCode = "WO-" + proOrderNo + str + "-" + serialNum;
            ddQty = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]);
            // 拆批大小<=需求
            keys = new Dictionary<string, string>();
            if(batchNum <= ddQty)
            {
                // 成品（加工批次）
                keys.Add("loginUser", loginUser);
                keys.Add("cSourceNo", ccSourceNo);
                keys.Add("cMatNo", cMatNo);
                keys.Add("Num", batchNum.ToString());
                keys.Add("cPOrderNo", cPOrderNo);
                keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                keys.Add("cReworkFlag", cReworkFlag);
                keys.Add("cOFlag", cOFlag);
                keys.Add("cCombination", cCombination);
                keys.Add("cBigBegProDate", cBigBegProDate);
                keys.Add("iBatchMult", iBatchMult.ToString());
                keys.Add("cInOutType", "");
                keys.Add("proLotOrderNoHalf", "");
                keys.Add("cBarCode", cBarCode);
                keys.Add("Coefficient", Coefficient);
                planOrderObj[cPOrderNo].Remove("json");
            }
            else
            {
                keys.Add("loginUser", loginUser);
                keys.Add("cSourceNo", ccSourceNo);
                keys.Add("cMatNo", cMatNo);
                keys.Add("Num", ddQty.ToString());
                keys.Add("cPOrderNo", cPOrderNo);
                keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                keys.Add("cReworkFlag", cReworkFlag);
                keys.Add("cOFlag", cOFlag);
                keys.Add("cCombination", cCombination);
                keys.Add("cBigBegProDate", cBigBegProDate);
                keys.Add("iBatchMult", iBatchMult.ToString());
                keys.Add("cBarCode", cBarCode);
                keys.Add("cInOutType", "");
                keys.Add("proLotOrderNoHalf", "");
                keys.Add("Coefficient", Coefficient);
                planOrderObj[cPOrderNo].Remove("json");
            }
            if (!proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson"))
            {
                list.Add(keys);
                string listJson = CommonMethod.Instance.ToJsonString(list);
                proOrderObj[proOrderNo][proLotOrderNo].Add("listJson", listJson);
            }
            else
            {
                string json = proOrderObj[proOrderNo][proLotOrderNo]["listJson"];
                List<Dictionary<string, string>> people = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
                people.Add(keys);
                string listJson1 = CommonMethod.Instance.ToJsonString(people);
                proOrderObj[proOrderNo][proLotOrderNo]["listJson"] = listJson1;
            }
            planOrderObjPara = planOrderObj;
            return proOrderObj;
        }

        /**
        * 遍历生产订单中的子销售订单函数
        * @param {obj} 生产订单与其对应的子销售订单对象
        * @param {cPOrderNo} 生产订单编号
        * @param {planOrderObj} 生产订单对象
        * @param {proOrderObj} 容器对象
        * @param {MatDataObj} 物料主数据对象
        * @param {BomDataObj} {BOM}数据对象
        * @param {batchNum} 拆批量
        * @param {batch} 切片数
        * @param {proLotOrderNo} 批次号
        * @param {loginUser} 登录用户
        * @param {serialNum} 流水号
        */
        private Dictionary<string,Dictionary<string,Dictionary<string,string>>> TraverseSource(Dictionary<string, Dictionary<string, Dictionary<string, string>>> obj, 
            string cPOrderNo, Dictionary<string, Dictionary<string, string>> planOrderObj, float batchNum, 
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> proOrderObj, string proLotOrderNo, 
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> RoutingObj, Dictionary<string, Dictionary<string, string>> BomDataObj,string loginUser, int serialNum, float c, float D_J, 
            out Dictionary<string, Dictionary<string, string>> planOrderObjPara)
        {
            Dictionary<string, string> keys = null;
            List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
            Dictionary<string, string> keys1 = null;
            List<Dictionary<string, string>> list1 = new List<Dictionary<string, string>>();
            try
            {
                float ddQty = 0;
                // 生产订单编号
                string proOrderNo = cPOrderNo;
                //// 生产部门
                string cProductDepNo = planOrderObj[cPOrderNo]["cProductDepNo"];
                //订单类别
                string MotypeCode = planOrderObj[cPOrderNo]["MotypeCode"];
                string Coefficient = "";
                if(planOrderObj[cPOrderNo]["Coefficient"] != null)
                {
                    Coefficient = planOrderObj[cPOrderNo]["Coefficient"];
                }
                string str = "";
                str = MotypeCode;
                // 交货期
                string dDeliveryDate = planOrderObj[cPOrderNo]["dDeliveryDate"];
                string cReworkFlag = "";
                string cOFlag = "";
                string cBigBegProDate = "";
                float iBatchMult = 0;
                if (planOrderObj[cPOrderNo].ContainsKey("josn"))
                {
                    string json = planOrderObj[cPOrderNo]["josn"];
                    JArray jsonArr = (JArray)JsonConvert.DeserializeObject(json);
                    //重工单标识
                    cReworkFlag = jsonArr[11].ToString();
                    //插单标识
                    cOFlag = jsonArr[12].ToString();
                    //大批量订单开始生产日期
                    cBigBegProDate = jsonArr[13].ToString();
                    //生产批量倍数
                    iBatchMult = 0;
                }
                else
                {
                    //重工单标识
                    cReworkFlag = planOrderObj[cPOrderNo]["cReworkFlag"];
                    //插单标识
                    cOFlag = planOrderObj[cPOrderNo]["cOFlag"];
                    //大批量订单开始生产日期
                    cBigBegProDate = planOrderObj[cPOrderNo]["cBigBegProDate"];
                    //生产批量倍数
                    iBatchMult = 0;
                }
                // 当前流水号
                int serialNum1 = serialNum + (int)c;
                // 半成品生产批次编号
                string proLotOrderNoHalf = "";
                // 钉卷条码值
                string cBarCodeHalf = "";
                //物料编号
                string cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                // 配比
                string cCombination = "";
                if (RoutingObj.ContainsKey(cMatNo))
                {
                     foreach(var RoutingCode in RoutingObj[cMatNo].Keys)
                    {
                        cCombination = RoutingObj[cMatNo][RoutingCode]["cCombination"];
                    }
                }
                // 条码值
                string cBarCode = "WO-" + proOrderNo + str + "-" + serialNum;
                // 指令类型
                string cInOutType = BomDataObj[cMatNo]["cInOutType"];
                // 如果指令类型为output则存在半成品，生成半成品生产批次编号
                if (cInOutType == "output")
                {
                    // 后2位流水号
                    serialNum1 = CommonMethod.Instance.GenerateID2(serialNum1, "000");
                    // 生产批次编号
                    proLotOrderNoHalf = proOrderNo + str + "-" + serialNum1;
                    // 钉卷条码值
                    cBarCodeHalf = "WO-" + proOrderNo + str + "-" + serialNum1;
                    if (!proOrderObj[proOrderNo].ContainsKey(proLotOrderNoHalf))
                    {
                        proOrderObj[proOrderNo].Add(proLotOrderNoHalf, new Dictionary<string, string>());
                    }
                }
                else
                {
                }
                string ccSourceNo = "";
                foreach(var cSourceNo in obj[cPOrderNo].Keys)
                {
                    ccSourceNo = cSourceNo;
                }
                ddQty = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]);
                // 拆批大小<=需求
                keys = new Dictionary<string, string>();
                keys1 = new Dictionary<string, string>();
                if (batchNum < ddQty)
                {

                    float putProQty = batchNum * float.Parse(Coefficient);
                    // 物料编号
                    cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                    keys.Add("loginUser", loginUser);
                    keys.Add("cSourceNo", ccSourceNo);
                    keys.Add("cMatNo", cMatNo);
                    keys.Add("Num", batchNum.ToString());
                    keys.Add("cPOrderNo", cPOrderNo);
                    keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                    keys.Add("cReworkFlag", cReworkFlag);
                    keys.Add("cOFlag", cOFlag);
                    keys.Add("cCombination", cCombination);
                    keys.Add("cBigBegProDate", cBigBegProDate);
                    keys.Add("iBatchMult", iBatchMult.ToString());
                    keys.Add("cBarCode", cBarCode);
                    keys.Add("cInOutType", "");
                    keys.Add("proLotOrderNoHalf", proLotOrderNoHalf);
                    keys.Add("Coefficient", Coefficient);
                    //planOrderObj[cPOrderNo].splice(batch, 1);
                    //batch++;
                    
                    if (cInOutType == "output")
                    {
                        // 半成品（钉卷批次）
                        cMatNo = BomDataObj[cMatNo]["cMatandResNo"];
                        proOrderObj[proOrderNo][proLotOrderNoHalf].Add("cProductDepNo", cProductDepNo);
                        proOrderObj[proOrderNo][proLotOrderNoHalf].Add("dDeliveryDate", dDeliveryDate);
                        proOrderObj[proOrderNo][proLotOrderNoHalf].Add("batchNum", proOrderObj[proOrderNo][proLotOrderNo]["batchNum"]);
                        keys1.Add("loginUser", loginUser);
                        keys1.Add("cSourceNo", ccSourceNo);
                        keys1.Add("cMatNo", cMatNo);
                        keys1.Add("Num", batchNum.ToString());
                        keys1.Add("cPOrderNo", cPOrderNo);
                        keys1.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                        keys1.Add("cReworkFlag", cReworkFlag);
                        keys1.Add("cOFlag", cOFlag);
                        keys1.Add("cCombination", cCombination);
                        keys1.Add("cBigBegProDate", cBigBegProDate);
                        keys1.Add("iBatchMult", iBatchMult.ToString());
                        keys1.Add("cInOutType", cInOutType);
                        keys1.Add("cBarCodeHalf", cBarCodeHalf);
                        keys1.Add("proLotOrderNoHalf", "");
                        keys1.Add("Coefficient", Coefficient);
                    }
                    planOrderObj[cPOrderNo].Remove("json");
                }
                else if(batchNum == ddQty)
                {
                    float putProQty = batchNum * float.Parse(Coefficient);
                    // 物料编号
                    cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                    // 成品（加工批次）
                    keys.Add("loginUser", loginUser);
                    keys.Add("cSourceNo", ccSourceNo);
                    keys.Add("cMatNo", cMatNo);
                    keys.Add("Num", batchNum.ToString());
                    keys.Add("cPOrderNo", cPOrderNo);
                    keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                    keys.Add("cReworkFlag", cReworkFlag);
                    keys.Add("cOFlag", cOFlag);
                    keys.Add("cCombination", cCombination);
                    keys.Add("cBigBegProDate", cBigBegProDate);
                    keys.Add("iBatchMult", iBatchMult.ToString());
                    keys.Add("cBarCode", cBarCode);
                    keys.Add("cInOutType", "");
                    keys.Add("proLotOrderNoHalf", proLotOrderNoHalf);
                    keys.Add("Coefficient", Coefficient);

                    if (cInOutType == "output")
                    {
                        // 半成品（钉卷批次）
                        if (D_J < 0 && D_J != -99999)
                        {
                            cMatNo = BomDataObj[cMatNo]["cMatandResNo"];
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("cProductDepNo", cProductDepNo);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("dDeliveryDate", dDeliveryDate);
                            float tt = float.Parse(planOrderObj[cPOrderNo]["dPlanQty"]) - (c - 1) * float.Parse(planOrderObj[cPOrderNo]["dProBatch"]);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("batchNum", tt.ToString());
                            keys1.Add("loginUser", loginUser);
                            keys1.Add("cSourceNo", ccSourceNo);
                            keys1.Add("cMatNo", cMatNo);
                            keys1.Add("Num", proOrderObj[proOrderNo][proLotOrderNoHalf]["batchNum"]);
                            keys1.Add("cPOrderNo", cPOrderNo);
                            keys1.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                            keys1.Add("cReworkFlag", cReworkFlag);
                            keys1.Add("cOFlag", cOFlag);
                            keys1.Add("cCombination", cCombination);
                            keys1.Add("cBigBegProDate", cBigBegProDate);
                            keys1.Add("iBatchMult", iBatchMult.ToString());
                            keys1.Add("cInOutType", cInOutType);
                            keys1.Add("cBarCodeHalf", cBarCodeHalf);
                            keys1.Add("proLotOrderNoHalf", "");
                            keys1.Add("Coefficient", Coefficient);
                        }else
                        {
                            cMatNo = BomDataObj[cMatNo]["cMatandResNo"];
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("cProductDepNo", cProductDepNo);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("dDeliveryDate", dDeliveryDate);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("batchNum", planOrderObj[cPOrderNo]["dProBatch"]);
                            keys1.Add("loginUser", loginUser);
                            keys1.Add("cSourceNo", ccSourceNo);
                            keys1.Add("cMatNo", cMatNo);
                            keys1.Add("Num", planOrderObj[cPOrderNo]["dProBatch"]);
                            keys1.Add("cPOrderNo", cPOrderNo);
                            keys1.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                            keys1.Add("cReworkFlag", cReworkFlag);
                            keys1.Add("cOFlag", cOFlag);
                            keys1.Add("cCombination", cCombination);
                            keys1.Add("cBigBegProDate", cBigBegProDate);
                            keys1.Add("iBatchMult", iBatchMult.ToString());
                            keys1.Add("cInOutType", cInOutType);
                            keys1.Add("cBarCodeHalf", cBarCodeHalf);
                            keys1.Add("proLotOrderNoHalf", "");
                            keys1.Add("Coefficient", Coefficient);
                        }
                    }
                    planOrderObj[cPOrderNo].Remove("json");
                }
                else
                {
                    // 物料编号
                    cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                    // 成品（加工批次）
                    keys.Add("loginUser", loginUser);
                    keys.Add("cSourceNo", ccSourceNo);
                    keys.Add("cMatNo", cMatNo);
                    keys.Add("Num", batchNum.ToString());
                    keys.Add("cPOrderNo", cPOrderNo);
                    keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                    keys.Add("cReworkFlag", cReworkFlag);
                    keys.Add("cOFlag", cOFlag);
                    keys.Add("cCombination", cCombination);
                    keys.Add("cBigBegProDate", cBigBegProDate);
                    keys.Add("iBatchMult", iBatchMult.ToString());
                    keys.Add("cBarCode", cBarCode);
                    keys.Add("cInOutType", "");
                    keys.Add("proLotOrderNoHalf", proLotOrderNoHalf);
                    keys.Add("Coefficient", Coefficient);

                    if(cInOutType == "output")
                    {
                        // 半成品（钉卷批次）
                        if (D_J < 0 && D_J != -99999)
                        {
                            cMatNo = BomDataObj[cMatNo]["cMatandResNo"];
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("cProductDepNo", cProductDepNo);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("dDeliveryDate", dDeliveryDate);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("batchNum", proOrderObj[proOrderNo][proLotOrderNo]["batchNum"]);
                            keys1.Add("loginUser", loginUser);
                            keys1.Add("cSourceNo", ccSourceNo);
                            keys1.Add("cMatNo", cMatNo);
                            keys1.Add("Num", ddQty.ToString());
                            keys1.Add("cPOrderNo", cPOrderNo);
                            keys1.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                            keys1.Add("cReworkFlag", cReworkFlag);
                            keys1.Add("cOFlag", cOFlag);
                            keys1.Add("cCombination", cCombination);
                            keys1.Add("cBigBegProDate", cBigBegProDate);
                            keys1.Add("iBatchMult", iBatchMult.ToString());
                            keys1.Add("cInOutType", cInOutType);
                            keys1.Add("cBarCodeHalf", cBarCodeHalf);
                            keys1.Add("proLotOrderNoHalf", "");
                            keys1.Add("Coefficient", Coefficient);
                        }else
                        {
                            cMatNo = BomDataObj[cMatNo]["cMatandResNo"];
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("cProductDepNo", cProductDepNo);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("dDeliveryDate", dDeliveryDate);
                            proOrderObj[proOrderNo][proLotOrderNoHalf].Add("batchNum", proOrderObj[proOrderNo][proLotOrderNo]["batchNum"]);
                            keys1.Add("loginUser", loginUser);
                            keys1.Add("cSourceNo", ccSourceNo);
                            keys1.Add("cMatNo", cMatNo);
                            keys1.Add("Num", ddQty.ToString());
                            keys1.Add("cPOrderNo", cPOrderNo);
                            keys1.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                            keys1.Add("cReworkFlag", cReworkFlag);
                            keys1.Add("cOFlag", cOFlag);
                            keys1.Add("cCombination", cCombination);
                            keys1.Add("cBigBegProDate", cBigBegProDate);
                            keys1.Add("iBatchMult", iBatchMult.ToString());
                            keys1.Add("cInOutType", cInOutType);
                            keys1.Add("cBarCodeHalf", cBarCodeHalf);
                            keys1.Add("proLotOrderNoHalf", "");
                            keys1.Add("Coefficient", Coefficient);
                        }
                    }
                    planOrderObj[cPOrderNo].Remove("json");
                }
                if (!proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson"))
                {
                    list.Add(keys);
                    string listJson = CommonMethod.Instance.ToJsonString(list);
                    proOrderObj[proOrderNo][proLotOrderNo].Add("listJson", listJson);
                }else
                {
                    string json = proOrderObj[proOrderNo][proLotOrderNo]["listJson"];
                    List<Dictionary<string, string>> people = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
                    people.Add(keys);
                    string listJson1 = CommonMethod.Instance.ToJsonString(people);
                    proOrderObj[proOrderNo][proLotOrderNo]["listJson"] = listJson1;
                }
                if (cInOutType == "output")
                {
                    if (!proOrderObj[proOrderNo][proLotOrderNoHalf].ContainsKey("listJson1"))
                    {
                        list1.Add(keys1);
                        string listJson = CommonMethod.Instance.ToJsonString(list1);
                        proOrderObj[proOrderNo][proLotOrderNoHalf].Add("listJson1", listJson);
                    }
                    else
                    {
                        string json = proOrderObj[proOrderNo][proLotOrderNoHalf]["listJson1"];
                        List<Dictionary<string, string>> people = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
                        people.Add(keys1);
                        string listJson1 = CommonMethod.Instance.ToJsonString(people);
                        proOrderObj[proOrderNo][proLotOrderNoHalf]["listJson1"] = listJson1;
                    }
                }  
            }
            catch (Exception e)
            {
                throw e;
            }
            planOrderObjPara = planOrderObj;
            return proOrderObj;
        }

        public Dictionary<string,Dictionary<string,Dictionary<string,Dictionary<string,string>>>> getBatchMatQty(Dictionary<string, Dictionary<string, Dictionary<string, string>>> proOrderObj,
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> obj, Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> ValidBOMObj)
        {
            var proLotMatQtyObj = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>();
            try
            {
                JArray jsonArr = null;
                float length = 0;
                // 遍历生产订单
                foreach(var proOrderNo in proOrderObj.Keys)
                {
                    // 遍历生产批次
                    foreach(var proLotOrderNo in proOrderObj[proOrderNo].Keys)
                    {
                        if(!proLotMatQtyObj.ContainsKey(proLotOrderNo))
                        {
                            length++;
                            proLotMatQtyObj.Add(proLotOrderNo, new Dictionary<string, Dictionary<string, Dictionary<string, string>>>());
                        }
                        //获取 proOrderObj中的json
                        //if (proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson"))
                        //{
                        //    var json = proOrderObj[proOrderNo][proLotOrderNo]["listJson"];
                        //    jsonArr = (JArray)JsonConvert.DeserializeObject(json);
                        //}
                        if (proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson"))
                        {
                            var json = proOrderObj[proOrderNo][proLotOrderNo]["listJson"];
                            jsonArr = (JArray)JsonConvert.DeserializeObject(json);
                        }
                        if (proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson1"))
                        {
                            var json = proOrderObj[proOrderNo][proLotOrderNo]["listJson1"];
                            jsonArr = (JArray)JsonConvert.DeserializeObject(json);
                        }

                        if (jsonArr.Count > 0)
                        {
                            for(int i = 0; i < jsonArr.Count; i++)
                            {
                                string cSourceNo = jsonArr[i]["cSourceNo"].ToString();
                                string cMatNo = jsonArr[i]["cMatNo"].ToString();
                                if (!proLotMatQtyObj[proLotOrderNo].ContainsKey(cMatNo))
                                {
                                    proLotMatQtyObj[proLotOrderNo].Add(cMatNo,new Dictionary<string, Dictionary<string, string>>());
                                }
                                // 拆批量
                                string Num = jsonArr[i]["Num"].ToString();
                                float batchNum = float.Parse(proOrderObj[proOrderNo][proLotOrderNo]["batchNum"]);
                                string cBatchNumber = jsonArr[i]["proLotOrderNoHalf"].ToString();
                                // 钉卷需求数量
                                float ddQty = float.Parse(obj[proOrderNo][cSourceNo]["dPlanQty"]);

                                bool t = ValidBOMObj.ContainsKey(proOrderNo);
                                bool tt = ValidBOMObj[proOrderNo].ContainsKey(cMatNo);
                                if (ValidBOMObj.ContainsKey(proOrderNo) && ValidBOMObj[proOrderNo].ContainsKey(cMatNo))
                                {
                                    float length1 = 0;
                                    foreach (var cMatandResNo in ValidBOMObj[proOrderNo][cMatNo].Keys)
                                    {
                                        if (cMatandResNo == "cBegProDate")
                                        {
                                            continue;
                                        }
                                        float cMatQty_Unit = 1;
                                        if (cMatandResNo.IndexOf('C') != -1)
                                        {
                                            //proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].cOrderType = '2';
                                            cMatQty_Unit = 1;
                                        }
                                        else
                                        {
                                            //proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].cOrderType = '1';
                                            // 生产订单需求量
                                            float dPlanQty =float.Parse(ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["dPlanQty"]);
                                            // 生产一个成品需要单位原材料量
                                            cMatQty_Unit = dPlanQty / ddQty;
                                        }
                                        if (!proLotMatQtyObj[proLotOrderNo][cMatNo].ContainsKey(cMatandResNo))
                                        {
                                            length1++; 
                                            //proLotMatQtyObj[proLotOrderNo][cMatNo].length = length1;
                                            proLotMatQtyObj[proLotOrderNo][cMatNo].Add(cMatandResNo,new Dictionary<string, string>());
                                            string value = (cMatQty_Unit* batchNum).ToString();
                                            proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cMatTotal", value);
                                        }
                                        else
                                        {
                                            string oldValue = proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo]["cMatTotal"];
                                            float ret = float.Parse(oldValue);
                                            ret += cMatQty_Unit * batchNum;
                                            proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo]["cMatTotal"] = ret.ToString();
                                        }
                                        if (cMatandResNo.IndexOf('C') != -1)
                                        {
                                            proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOrderType", "2");
                                            //cMatQty_Unit = 1;
                                        }
                                        else
                                        {
                                            proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOrderType", "1");
                                            // 生产订单需求量
                                            //let dPlanQty = ValidBOMObj[proOrderNo][cMatNo][cMatandResNo].dPlanQty;
                                            // 生产一个成品需要单位原材料量
                                            //cMatQty_Unit = Number(dPlanQty) / Number(ddQty);
                                        }
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOperationNo", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cOperationNo"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOperationName", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cOperationName"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOpSeq", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cOpSeq"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cInOutType", "input");
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cMatandResName", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cMatandResName"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cMatandResType", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cMatandResType"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("dWidth", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["dWidth"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("dLength", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["dLength"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cSpecifution", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cSpecifution"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cUnit", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cUnit"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCapacityLow", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cCapacityLow"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCapacityUp", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cCapacityUp"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCapacity", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cCapacity"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cBomid", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cBomid"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cSortSeq", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cSortSeq"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCateNo", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["cCateNo"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("dVoltage", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["dVoltage"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("Unit", ValidBOMObj[proOrderNo][cMatNo][cMatandResNo]["Unit"]);
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cBatchNumber", cBatchNumber);

                                    }
                                }
                            }
                        }else
                        {
                            throw new Exception("找不到proOrderObj Json");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return proLotMatQtyObj;
        }

        public Dictionary<string,Dictionary<string,Dictionary<string,Dictionary<string,string>>>> getProRouting(
            Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> proLotMatQtyObj, 
            Dictionary<string, Dictionary<string, Dictionary<string, string>>> RoutingObj)
        {
            var proRoutingObj = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>();
            try
            {
                foreach (var cMOLotNo in proLotMatQtyObj.Keys)
                {
                    string cOrderNo = cMOLotNo;
                    if (!proRoutingObj.ContainsKey(cOrderNo))
                    {
                        proRoutingObj.Add(cOrderNo, new Dictionary<string, Dictionary<string, Dictionary<string, string>>>());
                    }
                    foreach (var cMatNo in proLotMatQtyObj[cMOLotNo].Keys)
                    {
                        float dTransferTime = 0;
                        string cOrderType = "";
                        if (!proRoutingObj[cOrderNo].ContainsKey(cMatNo))
                        {
                            proRoutingObj[cOrderNo].Add(cMatNo,new Dictionary<string, Dictionary<string, string>>());
                        }
                        foreach (var num in proLotMatQtyObj[cMOLotNo][cMatNo].Keys)
                        {
                            cOrderType = proLotMatQtyObj[cMOLotNo][cMatNo][num]["cOrderType"];
                            continue;
                        }
                        if (RoutingObj.ContainsKey(cMatNo))
                        {
                            foreach(var cOperationNo in RoutingObj[cMatNo].Keys)
                            {
                                proRoutingObj[cOrderNo][cMatNo].Add(cOperationNo, new Dictionary<string, string>());
                                dTransferTime = float.Parse(RoutingObj[cMatNo][cOperationNo]["dTransferTime"]);
                                string cOperationName = RoutingObj[cMatNo][cOperationNo]["cOperationName"];
                                string cOpSeq = RoutingObj[cMatNo][cOperationNo]["cOpSeq"];
                                proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("cOrderType", cOrderType);
                                proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("cOperationName", cOperationName);
                                proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("cOpSeq", cOpSeq);
                                proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("dTransferTime", dTransferTime.ToString());
                            }
                        }
                    }
                }
            }
            catch(Exception e)
            {
                throw e;
            }
            return proRoutingObj;
        }
    }
}